<?php
/*
 * @Author: LDY dong2406@126.com
 * @Date: 2022-08-20 16:38:29
 * @LastEditors: LDY dong2406@126.com
 * @LastEditTime: 2022-09-16 23:29:43
 */

namespace Ldy\Traits;

use Closure;
use Illuminate\Support\Arr;

trait HasHooks{
    
    protected $hooks = [];

    /**
     * 注册闭包
     *
     * @param [type] $name
     * @param Closure $callback
     * @return $this
     */
    protected function registerHook($name, Closure $callback)
    {
        $this->hooks[$name][] = $callback;

        return $this;
    }

    /**
     * 执行闭包
     *
     * @param [type] $name
     * @param array $parameters
     * @return void
     */
    protected function callHooks($name, $parameters = [])
    {
        $hooks = Arr::get($this->hooks, $name, []);

        foreach ($hooks as $func) {
            if (!$func instanceof Closure) {
                continue;
            }

            $response = call_user_func($func, $this, $parameters);

            // if ($response instanceof Response) {
            return $response;
            // }
        }
    }

    /**
     * 注册保存数据之前的闭包
     *
     * @param Closure $callback
     * @return Closure
     */
    public function saving(Closure $callback)
    {
        return $this->registerHook('saving', $callback);
    }

    /**
     * 注册保存数据之后的闭包
     *
     * @param Closure $callback
     *
     * @return Closure
     */
    public function saved(Closure $callback)
    {
        return $this->registerHook('saved', $callback);
    }

    /**
     * 执行保存数据之前的闭包
     *
     * @return mixed
     */
    protected function callSaving()
    {
        return $this->callHooks('saving');
    }

    /**
     * 执行保存数据之后的闭包
     *
     * @return mixed|null
     */
    protected function callSaved()
    {
        return $this->callHooks('saved');
    }

    /**
     * 注册更新之前的闭包
     *
     * @return Closure
     */
    public function bUpdate(Closure $callback){
        return $this->registerHook('bUpdate', $callback);
    }

    /**
     * 注册更新之后的闭包
     *
     * @return Closure
     */
    public function aUpdate(Closure $callback){
        return $this->registerHook('aUpdate', $callback);
    }

     /**
     * 执行更新数据之前的闭包
     *
     * @return mixed
     */
    protected function callBeforeUpdate()
    {
        return $this->callHooks('bUpdate');
    }

    /**
     * 执行更新数据之后的闭包
     *
     * @return mixed|null
     */
    protected function callAfterUpdate()
    {
        return $this->callHooks('aUpdate');
    }
}